package cn.agiledata.bank.linkbank.impl.chinapay;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import cn.agiledata.bank.linkbank.exception.LinkBankException;
import cn.agiledata.bank.linkbank.impl.AbstractBankPayResponse;
import cn.agiledata.bank.linkbank.logic.DigitalSignValidatable;

/**
 * 中国银行电子网上支付响应
 * 
 * @author 马贤波
 * 
 */
public final class ChinapayNetPayResponse extends AbstractBankPayResponse
        implements DigitalSignValidatable {
    private static final BigDecimal HUNDRED = new BigDecimal(100);

    static final String[] RESPONSE_KEYS = {
            ChinapayNetConstant.RESPONSE_MERCHANT_ID,
            ChinapayNetConstant.RESPONSE_ORDER_ID,
            ChinapayNetConstant.RESPONSE_AMOUNT,
            ChinapayNetConstant.RESPONSE_CURRENCY_TYPE,
            ChinapayNetConstant.RESPONSE_DATE,
            ChinapayNetConstant.RESPONSE_TRANS_TYPE,
            ChinapayNetConstant.TRANS_STATUS,
            ChinapayNetConstant.BANK_GATE_ID,
            ChinapayNetConstant.EXT,
            ChinapayNetConstant.RESPONSE_DIGITAL_SIGN
            };

    private ChinapayOrderIdTransformer orderIdTransformer;

    private String publicKeyFilePath;

    public ChinapayNetPayResponse() {
        super();
        this.orderIdTransformer = new ChinapayOrderIdTransformer();
    }

    public void setPublicKeyFilePath(String publicKeyFilePath) {
        this.publicKeyFilePath = publicKeyFilePath;
    }

    public void setMessages(Map messages) throws LinkBankException {
        super.setMessages(messages);
        String merchantId = getMessage(ChinapayNetConstant.RESPONSE_MERCHANT_ID);
        this.orderIdTransformer.setMerchantId(merchantId);
        String date = getMessage(ChinapayNetConstant.RESPONSE_DATE);
        this.orderIdTransformer.setDate(date);
    }

    protected AbstractBankPayResponse getCopiedInstance() {
        ChinapayNetPayResponse response = new ChinapayNetPayResponse();
        response.orderIdTransformer = this.orderIdTransformer;
        response.publicKeyFilePath = this.publicKeyFilePath;
        return response;
    }

    protected String getSuccessReturnCode() {
        return ChinapayNetConstant.TRANS_STATUS_SUCCESS;
    }

    protected String[] getValidKeys() {
        return RESPONSE_KEYS;
    }

    protected boolean isValidKey(String key) {
        if (ChinapayNetConstant.RESPONSE_DIGITAL_SIGN.equals(key)) {
            return true;
        }
        return super.isValidKey(key);
    }

    public boolean isAmountValidatable() {
        return true;
    }

    public BigDecimal getAmount() {
        try {
            String amountValue = getMessage(ChinapayNetConstant.RESPONSE_AMOUNT);
            return new BigDecimal(amountValue).divide(HUNDRED, 2,
                    BigDecimal.ROUND_HALF_UP);
        } catch (Exception e) {
            return null;
        }
    }

    public String getOrderId() {
        String orderId = getMessage(ChinapayNetConstant.RESPONSE_ORDER_ID);
        return this.orderIdTransformer.orderId2TransId(orderId);
    }

    public String getReturnCode() {
        return getMessage(ChinapayNetConstant.TRANS_STATUS);
    }

    public String getDigitalSign() {
        return getMessage(ChinapayNetConstant.RESPONSE_DIGITAL_SIGN);
    }

    public boolean validateDigitalSign(String cryptoKey)
            throws LinkBankException {
        Map values = new HashMap();
        String[] keys = RESPONSE_KEYS;
        for (int i = 0; i < keys.length; i++) {
            values.put(keys[i], getMessage(keys[i]));
        }
        return ChinapayUtils.validateDigitalSign(values, getDigitalSign(),
                this.publicKeyFilePath);
    }

    public String getCryptoKeyDescription() {
        return null;
    }

    public boolean validateCryptoKey(String cryptoKey) {
        return true;
    }

}
